<template>
  <el-form :model="spuInfo" :rules="spuRules" label-width="100px" ref="spuFormRef">
    <el-form-item label="SPU名称" prop="spuName">
      <el-input placeholder="SPU名称" v-model="spuInfo.spuName"></el-input>
    </el-form-item>
    <el-form-item label="品牌" prop="tmId">
      <el-select placeholder="请选择品牌" v-model="spuInfo.tmId">
        <el-option v-for="tm in trademarkList" :key="tm.id" :label="tm.tmName" :value="tm.id" />
      </el-select>
    </el-form-item>
    <el-form-item label="SPU描述" prop="description">
      <el-input v-model="spuInfo.description" type="textarea" rows="3"></el-input>
    </el-form-item>
    <el-form-item label="SPU图片" prop="spuImageList">
      <el-upload v-model:file-list="spuInfo.spuImageList" :action="`${BASE_URL}/admin/product/upload`"
       list-type="picture-card" 
       :on-preview="handlePictureCardPreview" 
       :on-remove="handleRemove"
       :on-success="handleAvatarSuccess" 
       :before-upload="beforeAvatarUpload">
        <el-icon>
          <Plus />
        </el-icon>
      </el-upload>
      <el-dialog v-model="dialogVisible">
        <img w-full :src="dialogImageUrl" alt="Preview Image" />
      </el-dialog>
    </el-form-item>
    <el-form-item label="销售属性" prop="spuSaleAttrList">
      <el-select v-model="spuInfo.spuSaleAttr" :placeholder="`还剩下${filterBaseSaleAttrList.length}个未选择`">
        <el-option v-for="bs in filterBaseSaleAttrList" :key="bs.id" :label="bs.name" :value="bs.name" />
      </el-select>
      <el-button type="primary" @click="addSpuSaleAttr" :disabled="!spuInfo.spuSaleAttr">添加销售属性</el-button>
      <el-table border :data="spuInfo.spuSaleAttrList">
        <el-table-column label="序号" width="80px" type="index" align="center"></el-table-column>
        <el-table-column label="属性名" prop="saleAttrName" align="center" width="100px"></el-table-column>
        <el-table-column label="属性值名称列表">
          <template v-slot="{row,$index}">
           <el-tag v-for="tag in row.spuSaleAttrValueList" :key="tag" class="mx-1" closable
          :disable-transitions="false" @close="handleClose(row,tag)" >
            {{ tag.saleAttrValueName }}
          </el-tag>
          <el-input v-if="row.inputVisible" ref="InputRef" v-model="inputValue" class="ml-1 w-20"
            size="small" @keyup.enter="handleInputConfirm(row)" @blur="handleInputConfirm(row)"/>
          <el-button v-else class="button-new-tag ml-1" size="small" @click="showInput(row)">
            + 添加新属性
          </el-button>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="100px" align="center">
          <template v-slot="{row,$index}">
            <el-popconfirm confirm-button-text="确定" cancel-button-text="取消" :icon="InfoFilled" icon-color="#626AEF" title="真的确定要删除此条数据么?" @confirm="deleteAttr($index)">
                <template #reference>
                  <el-button title="删除" type="danger" size="small" :icon="Delete" />
                </template>
              </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
    </el-form-item>
    <el-form-item>
      <el-button type="primary" @click="spuSubmitForm(spuFormRef)">保存</el-button>
      <el-button @click="emits('changeScene',1)">取消</el-button>
    </el-form-item>
  </el-form>
</template>

<script lang="ts">
export default {
  name: 'SpuForm'
}
</script>
<script lang="ts" setup>
import {ref,reactive,onMounted,computed,nextTick} from 'vue'
import { Plus,Delete ,InfoFilled} from '@element-plus/icons-vue'
import  { ElMessage ,ElInput} from 'element-plus'
import type {UploadProps, UploadFile, UploadUserFile,UploadFiles, FormInstance, FormRules } from 'element-plus'
import { reqGetAllTrademarkList, reqGetBaseSaleAttrList,reqGetSpuImageList,reqGetSpuSaleAttrList,reqSaveSpuInfo, reqUpdateSpuInfo } from '@/api/product/spu'
import {useCategoryListStore} from '@/stores/categoryList'

const categoryStore = useCategoryListStore()
// 实现自定义跳转
const emits = defineEmits(["changeScene"])

const props = defineProps(['currentSpuInfo'])

const inputValue = ref('')
const dynamicTags = ref(['Tag 1', 'Tag 2', 'Tag 3'])
const inputVisible = ref(false)
const InputRef = ref<InstanceType<typeof ElInput>>()

const dialogImageUrl = ref('')
const dialogVisible = ref(false)
const fileList = ref([])
// 上传图片地址
const BASE_URL = import.meta.env.VITE_API_URL;
// 定义两个变量 来存储品牌列表和基础销售属性
const trademarkList = ref([])
const baseSaleAttrList = ref([])

// 定义一个存储spu相关数据的变量
const spuInfo = reactive({
  spuName: '',
  tmId: '', // spu品牌
  description: '', // spu描述
  spuImageList: [], // 存储spu图片的数组
  spuSaleAttrList: [], // 基本销售属性
  spuSaleAttr:'', // 收集选中的属性 颜色 版本 尺寸
  category3Id:'', // 三级id
  ...props.currentSpuInfo
})
const formSize = ref('default')
const spuFormRef = ref<FormInstance>()

// 添加校验规则
const spuRules = reactive<FormRules>({
  spuName :[
    {required:true,message:"请输入SPU名称",trigger:"blur"},
    {min:1,max:10,message:"SPU名称在1-10个字符之间",trigger:"blur"}
  ],
   tmId: [{ required: true, message: '请选择SPU品牌', trigger: 'change' }],
   description: [{ required: true, message: '请输入SPU描述', trigger: 'blur' }],
   spuImageList: [{ required: true, message: '请选择一张图片', type: 'array', trigger: 'change' }],
   spuSaleAttrList: [{ required: true, message: '请至少添加一个属性', type: 'array', trigger: 'click' }]
})

//  1. 当组件渲染完毕的时候 就要发送请求 同时发送这两个请求
onMounted(async()=>{
  // 我们可以借助一个Promise.all([])方法，一次性发送多个请求 当请求成功后 会将数据按书写顺序依次赋值 只要成功就会按书写顺序 不管快慢
  // 如果有一个是失败的 则整体都会失败
  try {
    let promise = [reqGetAllTrademarkList(),reqGetBaseSaleAttrList()]
    const id = spuInfo.id
    if(id){
      // 如果有id说明此时是编辑操作
      promise = promise.concat([reqGetSpuImageList(id),reqGetSpuSaleAttrList(id)])
    }
    const [responseTrademarkList,responseBaseSaleAttrList,responseSpuImageList, responseSpuSaleAttrList] = await Promise.all(promise)
    trademarkList.value = responseTrademarkList
    baseSaleAttrList.value = responseBaseSaleAttrList
    if(responseSpuImageList && responseSpuSaleAttrList){
      spuInfo.spuImageList = responseSpuImageList.map(item=>{
        return {
          ...item,
          name:item.imgName,
          url:item.imgUrl,
        }
      })
      spuInfo.spuSaleAttrList = responseSpuSaleAttrList
    }
  }catch(error){
    ElMessage.error("获取属性失败")
  }
})
// 缩略图上传相关的事件处理程序
// 2. 删除图片是时执行的事件处理程序
const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
  console.log(uploadFile, uploadFiles)
  spuInfo.spuImageList = uploadFiles
}
// 3. 图片预览时要执行的事件处理程序
const handlePictureCardPreview: UploadProps['onPreview'] = uploadFile => {
  dialogImageUrl.value = uploadFile.url!
  dialogVisible.value = true
}
// 4. 图片上传成功后要执行的事件处理程序
const handleAvatarSuccess: UploadProps['onSuccess'] = (response: any, uploadFile: UploadFile, uploadFiles: UploadFiles) => {
  console.log(response, uploadFile,uploadFiles)
  // spuInfo.spuImageList.push({
  //   imgName: uploadFile.name,
  //   imgUrl: response.data
  // })

  4
  // 清空校验规则
  spuFormRef.value!.clearValidate(['spuImageList'])
}
// 5. 图片上传之前校验时要执行的事件处理程序
const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
   const imgTypes = ["image/jpeg", "image/jpg", "image/png"];
  // if (rawFile.type !== "image/jpeg") {
  if (!imgTypes.includes(rawFile.type)) {
    ElMessage.error("上传图片的格式只能是jpg/png/jpeg,请重新选择");
    return false;
  } else if (rawFile.size / 1024 / 1024 > 2) {
    ElMessage.error("图片大小不能超过2M,请重新选择...!");
    return false;
  }
  return true;
}
// 6. 添加销售属性值
const addSpuSaleAttr = () => {
  const spuSaleAttrList = spuInfo.spuSaleAttrList
  if (spuSaleAttrList.length && !spuSaleAttrList.every(item => item.spuSaleAttrValueList.length)) {
    ElMessage.error('有属性值为空，请添加...')
    return // 不要添加了
  }
  const id = baseSaleAttrList.value.find(item=>item.name==spuInfo.spuSaleAttr).id
  spuInfo.spuSaleAttrList.push({
    baseSaleAttrId:id,
    inputVisible: false,
    saleAttrName: spuInfo.spuSaleAttr,
    spuSaleAttrValueList: []
  })
  spuInfo.spuSaleAttr = '' // 清空下拉框选项

  // 清空输入框的值
  spuInfo.spuSaleAttr = ''

  // 清空校验规则
  spuFormRef.value!.clearValidate(['spuSaleAttrList'])
}
// 7. 使用计算属性来计算剩余的基础销售属性
const filterBaseSaleAttrList = computed(()=>{
  return baseSaleAttrList.value.filter(baseSale=>{
    return !spuInfo.spuSaleAttrList.find(item=>baseSale.name===item.saleAttrName)
  })
})
// 8. 清除当前属性
const deleteAttr = (index:number) =>{
  spuInfo.spuSaleAttrList.splice(index,1)
}

const handleClose = (row,tag) => {
  // 查找tag所在数组中的索引值
  let index = row.spuSaleAttrValueList.indexOf(tag)
  row.spuSaleAttrValueList.splice(index,1)
}

const showInput = (row) => {
  // inputVisible.value = true
  row.inputVisible = true
  nextTick(() => {
    InputRef.value!.input!.focus()
  })
}
 // 添加属性值失去焦点或是回车后执行的函数
const handleInputConfirm = (row) => {
  if (inputValue.value) {
    // 判断添加的属性值是不是重复的
   if(row.spuSaleAttrValueList.find(item=>item.saleAttrValueName===inputValue.value)){
    ElMessage.error("属性值不能重复,请更换新的属性值...")
    row.inputVisible = false
    inputValue.value = ''
    return 
   }
   const id = baseSaleAttrList.value.find(item=>item.name===row.saleAttrName).id
   row.spuSaleAttrValueList.push({
    baseSaleAttrId:id,
      saleAttrValueName: inputValue.value,
      saleAttrName: row.saleAttrName
    })
  }
   // inputVisible.value = false
  row.inputVisible = false
  inputValue.value = ''
  
}

// 提交前的校验
const spuSubmitForm = async(formEl:FormInstance|undefined)=>{
 if(!formEl) return 
 await formEl.validate(async(valid,fields)=>{
  if(valid){
    // 再判断一下，基础销售是不是有属性值 如果有一项没有值 不能提交
    const spuSaleAttrList = spuInfo.spuSaleAttrList
    if(spuSaleAttrList.length&&!spuSaleAttrList.every(item=>item.spuSaleAttrValueList.length)){
      ElMessage.error('有属性值为空，请添加属性值')
      return 
    }
     // 提交一下图片的内容
    spuInfo.spuImageList = spuInfo.spuImageList.map(item=>{
      return {
        imgName:item.name,
        imgUrl:item.response?.data || item.imgUrl
      }
    })

    spuInfo.category3Id = categoryStore.category3Id
    if(spuInfo.id){
      // 此时是更新操作
      await reqUpdateSpuInfo(spuInfo)
    }else{
      // 添加spuInfo
      await reqSaveSpuInfo(spuInfo)
    }
    ElMessage.success('操作spu成功...')
    // 跳转到列表页
    emits('changeScene',1)
  }else{
    // console.log('error submit!',false);
    console.log('提交失败');
    
  }
 })
}
</script>

<style>
</style>